/*
 * Copyright (C) 2008-2011 CBDP Consortium
 * 
 * All rights reserved.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution.
 * 
 * This software consists of contributions made by many individuals, 
 * listed below:
 *
 * Author: 	Xabier Laiseca <xabier.laiseca@deusto.es>
 * 			David Ausín <david.ausin@deusto.es>
 */
package cbdp.server.contextreasoner.impl.contextmanager.online.model;

import cbdp.server.contextreasoner.model.exceptions.InvalidDatatypeException;
import cbdp.server.contextreasoner.model.exceptions.NotExistingInstanceException;
import cbdp.server.contextreasoner.model.exceptions.NotExistingPropertyException;

import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
import com.hp.hpl.jena.graph.impl.LiteralLabel;
import com.hp.hpl.jena.graph.impl.LiteralLabelFactory;
import com.hp.hpl.jena.ontology.DatatypeProperty;
import com.hp.hpl.jena.ontology.Individual;
import com.hp.hpl.jena.ontology.OntResource;
import com.hp.hpl.jena.rdf.model.Literal;
import com.hp.hpl.jena.rdf.model.Property;
import com.hp.hpl.jena.rdf.model.Resource;
import com.hp.hpl.jena.util.iterator.ExtendedIterator;

public class Checker
{
	private final static String PROPERTY_INSTANCE_NOT_FOUND_MESSAGE = "The property does not exists";
	
	private final static String NULL_PARAMETER_EXCEPTION_1 = "The parameter ";
	private final static String NULL_PARAMETER_EXCEPTION_2 = " can not be null";
	
	public static void checkNullResource(final Resource resource) throws NotExistingInstanceException
	{
		if (resource == null)
		{
			throw new NotExistingInstanceException("The referenced instance does not exist");
		}
	}
	
	public static void checkNullIndividual(final Individual referencedIndividual) throws NotExistingInstanceException
	{
		if (referencedIndividual == null)
		{
			throw new NotExistingInstanceException("The referenced instance does not exist");
		}
	}

	public static void checkNullProperty(final Property property) throws NotExistingPropertyException
	{
		if (property == null)
		{
			throw new NotExistingPropertyException(PROPERTY_INSTANCE_NOT_FOUND_MESSAGE);
		}
	}
	
	public static void checkNullParameter(final Object parameter, final String parameterName)
	{
		if (parameter == null)
		{
			throw new NullPointerException(NULL_PARAMETER_EXCEPTION_1 + parameterName.trim() + NULL_PARAMETER_EXCEPTION_2); 
		}
	}
	
	public static void checkValidValue(final Literal literal, final DatatypeProperty datatypeProperty) throws InvalidDatatypeException
	{
		if (!isValidValue(literal, datatypeProperty))
		{
			throw new InvalidDatatypeException("The value type is not valid");
		}
	}
	
	private static boolean isValidValue(final Literal literal, final DatatypeProperty datatypeProperty)
	{
		
		boolean isValid = false;
		
		final ExtendedIterator<? extends OntResource> it = datatypeProperty.listRange();
		
		while(it.hasNext())
		{
			final OntResource res = it.next();
			
			if (res.getLocalName() != null)
			{
				final XSDDatatype datatype = new XSDDatatype(res.getLocalName());
				final LiteralLabel label = LiteralLabelFactory.create(literal.getValue());
				
				if (datatype.isBaseTypeCompatible(label))
				{
					isValid = true;
					break;
				}
			}
			else if (datatypeProperty.getRange().asDataRange().getOneOf().contains(literal))
			{
				isValid = true;
				break;
			}
		}
		
		return isValid;
	}
}
